/* Zatok - язык программирования текстовых игр
 * (С) 2010 - 2012 Меркулов Матвей Юрьевич
 * Код лицензирован под лицензией GNU LGPL
 * Вы можете прочитать текст лицензии по адресу:
 * http://www.gnu.org/copyleft/lesser.html
 * или прочитать русский перевод по адресу:
 * http://ru.wikisource.org/wiki/GNU_Lesser_General_Public_License
 */

package base.function.operator;

import base.function.CFunction;
import base.value.CFloatValue;
import base.value.CIntValue;
import base.value.CValue;
import base.value.CValue.CType;

public abstract class CNumericBinaryFunction extends CFunction {
	private CIntValue ReturnedIntValue = new CIntValue( 0 );
	private CFloatValue ReturnedFloatValue = new CFloatValue( 0f );
	
						
	
	
	@Override
	public void Init() {
		AssertParam( 2 );
	}

	
	
	@Override
	public CValue GetValue() {
		CValue Value0 = Param[ 0 ].GetValue();
		CValue Value1 = Param[ 1 ].GetValue();
		if ( GetType( Value0, Value1 ) == CType.Float ) {
			ReturnedFloatValue.Value = ToFloat( Value0, Value1 );
			return ReturnedFloatValue;
		} else {
			ReturnedIntValue.Value = ToInt( Value0, Value1 );
			return ReturnedIntValue;
		}
	}
	
	
	
	public CType GetType( CValue Value0, CValue Value1 ) {
		CType Type0 = NumericType( Value0 );
		CType Type1 = NumericType( Value1 );
		if ( Type0 == CType.Float && ( Type1 == CType.Float || Type1 == CType.Int ) ) return CType.Float;
		if ( Type0 == CType.Int  ) {
			if ( Type1 == CType.Float ) return CType.Float;
			if ( Type1 == CType.Int ) return CType.Int;
		}
		Error( "Параметры функции должны быть числовыми" );
		return null;
	}
	



	@Override
	public String ToString() {
		CValue Value0 = Param[ 0 ].GetValue();
		CValue Value1 = Param[ 1 ].GetValue();
		if ( GetType( Value0, Value1 ) == CType.Float ) {
			return String.valueOf( ToFloat( Value0, Value1 ) );
		} else {
			return String.valueOf( ToInt( Value0, Value1 ) );
		}
	}
	
	

	@Override
	public float ToFloat() {
		CValue Value0 = Param[ 0 ].GetValue();
		CValue Value1 = Param[ 1 ].GetValue();
		if ( GetType( Value0, Value1 ) == CType.Float ) {
			return ToFloat( Value0, Value1 );
		} else {
			return (float) ToInt( Value0, Value1 );
		}
	}
	
	

	@Override
	public int ToInt() {
		CValue Value0 = Param[ 0 ].GetValue();
		CValue Value1 = Param[ 1 ].GetValue();
		if ( GetType( Value0, Value1 ) == CType.Float ) {
			return (int) ToFloat( Value0, Value1 );
		} else {
			return ToInt( Value0, Value1 );
		}
	}
	
	
	
	public abstract float ToFloat( CValue Value0, CValue Value1 );
		
	public abstract int ToInt( CValue Value0, CValue Value1 );
}
